package com.vertxExample.starter;

import io.vertx.config.ConfigRetriever;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.mysqlclient.MySQLConnectOptions;
import io.vertx.mysqlclient.MySQLPool;
import io.vertx.sqlclient.*;

import java.time.OffsetDateTime;
import java.util.ArrayList;

/**
 * 解决回调地狱
 * 使用promise来解决
 */
public class FuturePromiseVerticle extends AbstractVerticle {
	Router router;
	PoolOptions poolOptions = new PoolOptions()
		.setMaxSize(5);
	MySQLPool client;

	@Override
	public void start(Promise<Void> startPromise) throws Exception {

		ConfigRetriever retriever = ConfigRetriever.create(vertx);

		retriever.getConfig(ar -> {
			JsonObject config = ar.result();
			//如果读取成功，再去进行配置
			if (ar.succeeded()) {
				MySQLConnectOptions connectOptions = new MySQLConnectOptions()
					.setPort(Integer.parseInt(config.getValue("port").toString()))
					.setHost(config.getString("host"))
					.setDatabase(config.getString("database"))
					.setUser(config.getString("user"))
					.setPassword(config.getString("password"));
				Router router = Router.router(vertx);
				client = MySQLPool.pool(vertx, connectOptions, poolOptions);


				router.route("/test/list").handler(req -> {
					Integer page = Integer.valueOf(req.request().getParam("page"));
					var offset = (page - 1) * 4;
					// 1. 获取数据库连接
					this.getCon()
						.compose(con -> this.getRows(con, offset))
						.onSuccess(rows -> {
							//3. 加工数据返回客户端
							var list = new ArrayList<JsonObject>();

							rows.forEach(item -> {
								var json = new JsonObject();
								json.put("id", item.getValue("id"));
								json.put("userName", item.getValue("userName"));
								json.put("passWord", item.getValue("passWord"));
								list.add(json);
							});
							req.response()
								.putHeader("content-type", "application/json")
								.end(list.toString());
						})
						.onFailure(rows -> {
							System.out.println(rows.getCause());
							System.out.println("fail");
						});
				});

				// config url
				vertx.createHttpServer().requestHandler(router).listen(8888, http -> {
					if (http.succeeded()) {
						startPromise.complete();
						System.out.println("HTTP server started on port 8888");
					} else {
						startPromise.fail(http.cause());
					}
				});
			} else {

			}
		});


	}

	// 第一步 获得数据库连接
	private Future<SqlConnection> getCon() {
		Promise<SqlConnection> promise = Promise.promise();
		client.getConnection(ar1 -> {
			if (ar1.succeeded()) {
				SqlConnection connection = ar1.result();
				promise.complete(connection);
			} else {
				promise.fail(ar1.cause());
			}
		});
		// promise.future() 生成 promise的实例
		return promise.future();
	}

	private Future<RowSet<Row>> getRows(SqlConnection conn, Integer offset) {
		Promise<RowSet<Row>> promise = Promise.promise();
		String sql = "SELECT * FROM users limit 4 offset ?";
		conn.preparedQuery(sql).execute(Tuple.of(offset), ar2 -> {
			conn.close();
			if (ar2.succeeded()) {
				promise.complete(ar2.result());
			} else {
				promise.fail(ar2.cause());
			}
		});
		return promise.future();
	}
}
